package task

import (
	"encoding/json"
	"fmt"

	// "strconv"
	"tushare/model/aliyun/ecs"
	modelTask "tushare/model/task"
	"tushare/service/aliyunCli"
	"tushare/service/task"

	"path/filepath"

	"time"

	"io/ioutil"
	"log"
	"os"

	"bytes"
	"tushare/service/shell"

	serviceSsh "tushare/service/ssh"

	"github.com/golang-module/carbon"
	"golang.org/x/crypto/ssh"
)

func ConsumeAppTask() {
	jsonMap := make(map[string]interface{})
	appTask := modelTask.UserTaskByStatus(0)
	for _, v := range appTask {
		json.Unmarshal([]byte(v.TaskJson), &jsonMap)
		aea := ecs.AliyunEcsApp{}
		aea.Status = 2
		serviceSsh := new(serviceSsh.Ssh)
		if v.TaskType == "install_nginx" {
			serviceSsh.InstallApp("nginxSbin", jsonMap["ip"].(string))

			aea.Status = 5
			aea.InstallPath = "/usr/local/nginx/sbin/nginx"
		} else if v.TaskType == "install_redis" {
			serviceSsh.InstallApp("redis", jsonMap["ip"].(string))

			aea.Status = 5
			aea.InstallPath = "/usr/local/redis-6.2.6"
		} else if v.TaskType == "install_maven" {
			serviceSsh.InstallApp("maven", jsonMap["ip"].(string))

			aea.Status = 5
			aea.InstallPath = "/usr/local/apache-maven-3.8.4"
		} else if v.TaskType == "install_java" {
			serviceSsh.InstallApp("java", jsonMap["ip"].(string))

			aea.Status = 5
			aea.InstallPath = "/usr/java/jdk1.8.0_212"
		} else if v.TaskType == "install_hadoop" {
			serviceSsh.InstallApp("hadoop", jsonMap["ip"].(string))

			aea.Status = 1
			aea.InstallPath = "/home/hadoop/app/hadoop-2.6.0-cdh5.7.0"
		} else if v.TaskType == "install_scala" {
			serviceSsh.InstallApp("scala", jsonMap["ip"].(string))

			aea.Status = 1
			aea.InstallPath = "/usr/local/scala-2.13.7"
		} else if v.TaskType == "install_kafka" {
			serviceSsh.InstallApp("kafka", jsonMap["ip"].(string))

			aea.Status = 5
			aea.InstallPath = "/usr/local/kafka_2.13-3.0.0"
		} else if v.TaskType == "install_spark" {
			serviceSsh.InstallApp("spark", jsonMap["ip"].(string))

			aea.Status = 5
			aea.InstallPath = "/usr/local/spark-2.2.0-bin-2.6.0-cdh5.7.0"
		}

		appId := int64(jsonMap["ecs_app_id"].(float64))
		ecs.AliyunEcsAppUpdate(appId, aea)

		ut := modelTask.UserTask{}
		ut.Status = 1
		modelTask.UserTaskUpdate(v.Id, ut)
	}
}

func ConsumeTask() {
	ecsList := ecs.AliyunEcsListByStatus(0)
	for _, v := range ecsList {
		if v.TaskType == "create_ecs" {
			t := new(task.Task)
			instanceId := t.CreateEcs(v)
			v.InstanceId = instanceId
			t.InitApp(v)
		} else if v.TaskType == "install_hadoop" {
			installHadoop(v)
		}
	}
}

func DeleteInstance() {
	ecsList := ecs.AliyunEcsListAll()

	for _, v := range ecsList {
		timeStr := carbon.Now().ToDateTimeString()
		diff := carbon.Parse(timeStr).DiffInHours(carbon.Parse(v.CreateTime))
		if diff >= 0 {
			continue
		}
		di := new(aliyunCli.DeleteInstance)
		res := di.DeleteInstance(v.InstanceId)
		if !res {
			continue
		}

		ae := ecs.AliyunEcs{}
		ae.IsDelete = 1
		ecs.AliyunEcsUpdate(v.Id, ae)

	}
}

func installHadoop(v ecs.AliyunEcs) {
	keyPairName := "hadoop_two"
	ae := ecs.AliyunEcs{}
	ae.TaskRemark = "创建阿里云ecs.c6a.xlarge中"
	ecs.AliyunEcsUpdate(v.Id, ae)
	ci := new(aliyunCli.CreateInstance)
	id := ci.CreateInstance(v.RegionId, v.ZoneId, v.InstanceType)
	time.Sleep(time.Second * 30)
	ae.TaskRemark = "阿里云ecs.c6a.xlarge创建成功"
	ae.InstanceName = "hadoop"
	ae.RegionId = "cn-hangzhou-i"
	ae.InstanceId = id
	ae.ImageId = "centos_7_8_x64_20G_alibase_20211028.vhd"
	ecs.AliyunEcsUpdate(v.Id, ae)

	ae.TaskRemark = "阿里云ecs.c6a.xlarge创建公网IP"
	ecs.AliyunEcsUpdate(v.Id, ae)
	ai := new(aliyunCli.AllocatePublicIpAddress)
	ai.AllocatePublicIpAddress(id)
	time.Sleep(time.Second * 30)
	ae.TaskRemark = "阿里云ecs.c6a.xlarge创建公网IP创建成功"
	ecs.AliyunEcsUpdate(v.Id, ae)

	ae.TaskRemark = "阿里云ecs.c6a.xlarge绑定登录秘钥"
	ecs.AliyunEcsUpdate(v.Id, ae)
	akp := new(aliyunCli.AttachKeyPair)
	akp.AttachKeyPair(id, keyPairName)
	time.Sleep(time.Second * 30)
	ae.TaskRemark = "阿里云ecs.c6a.xlarge登录秘钥绑定成功"
	ecs.AliyunEcsUpdate(v.Id, ae)

	ae.TaskRemark = "阿里云ecs.c6a.xlarge启动"
	ecs.AliyunEcsUpdate(v.Id, ae)
	si := new(aliyunCli.StartInstance)
	si.StartInstance(id)
	time.Sleep(time.Second * 30)
	ae.TaskRemark = "阿里云ecs.c6a.xlarge启动成功"
	ecs.AliyunEcsUpdate(v.Id, ae)

	ae.TaskRemark = "开始登录ecs.c6a.xlarge"
	ecs.AliyunEcsUpdate(v.Id, ae)
	di := new(aliyunCli.DescribeInstances)
	ip := di.DescribeInstances(id)
	ae.Ip = ip
	ecs.AliyunEcsUpdate(v.Id, ae)
	// ip := "47.99.99.198"

	host := fmt.Sprintf("%s:22", ip)
	// fmt.Println(host)
	//key := []byte(conf.RSAPRIVATEKEY)
	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		fmt.Println(err)
	}
	filePathStr := fmt.Sprintf("%s/%s", dir, "sshKey.txt")
	content, err := ioutil.ReadFile(filePathStr)
	if err != nil {
		fmt.Println(err)
	}
	key := content

	signer, err := ssh.ParsePrivateKey(key)
	if err != nil {
		log.Fatalf("parse key failed:%v", err)
	}

	// An SSH client is represented with a ClientConn.
	//
	// To authenticate with the remote server you must pass at least one
	// implementation of AuthMethod via the Auth field in ClientConfig,
	// and provide a HostKeyCallback.
	config := &ssh.ClientConfig{
		User:            "root",
		Auth:            []ssh.AuthMethod{ssh.PublicKeys(signer)},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
		Timeout:         time.Second * 3600,
	}
	client, err := ssh.Dial("tcp", host, config)
	if err != nil {
		log.Fatal("Failed to dial: ", err)
	}
	defer client.Close()

	// Each ClientConn can support multiple interactive sessions,
	// represented by a Session.
	session, err := client.NewSession()
	if err != nil {
		log.Fatal("Failed to create session: ", err)
	}
	defer session.Close()

	ae.TaskRemark = "开始安装Hadoop测试环境"
	ecs.AliyunEcsUpdate(v.Id, ae)
	// Once a Session is created, you can execute a single command on
	// the remote side using the Run method.
	var b bytes.Buffer
	session.Stdout = &b
	installHadoop := (new(shell.InstallApp)).InstallHadoop()
	if err := session.Run(installHadoop); err != nil {
		log.Fatal("Failed to run: " + err.Error())
	}

	ae.TaskRemark = "Hadoop测试环境安装成功"
	ae.Status = 1
	ecs.AliyunEcsUpdate(v.Id, ae)
}
